﻿using System;
using System.Collections.Generic;
using System.Text;
using OpenComposite.Base.Designer;
using System.Drawing;
using System.Windows.Forms;
using OpenComposite.Repository.Properties;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.Designer.Org
{
	public class OrgUnitSymbol : CollapsableSymbol
	{
		public OrgUnitSymbol()
			: base()
		{
			init();
		}

		public override void InitializeNew(IServiceProvider serviceProvider)
		{
			base.InitializeNew(serviceProvider);
		}

		public override void InitializeLoaded()
		{
			base.InitializeLoaded();
		}

		private UserSymbol _users = new UserSymbol();

		private int _width = 0;

		private int _orgUnitID;

		public int OrgUnitID
		{
			get { return _orgUnitID; }
			set { _orgUnitID = value; }
		}

		public int ArrangedWidth
		{
			get
			{
				if ( _width == 0 )
					return Width;
				else
					return _width;
			}
			set { _width = value; }
		}

		private void init()
		{
			// private init

			// init
			this.BeginUpdate();

			this.Name = "OrgUnit";
			this.Text = "Department";
			this.Border = BorderType.RoundedRectangle;
			//this.BackColor = Color.LightBlue;
			//this.BackColor2 = Color.SteelBlue;

			this.ExpandedBackColor = Color.LightBlue;
			this.ExpandedBackColor2 = Color.SteelBlue;
			this.ExpandedBorderColor = Color.DarkBlue;
			this.ExpandedSize = new Size(170, 220);

			this.CollapsedBackColor = Color.LightBlue;
			this.CollapsedBackColor2 = Color.SteelBlue;
			this.CollapsedBorderColor = Color.DarkBlue;
			this.CollapsedSize = new Size(170, 110);

			this.CollapseSign = CollapseSign.DoubleArrow;
			this.CollapseSignPosition = CollapseSignPosition.TopRight;

			this.IsCollapsed = true;

			this.BackBrushMode = BackgroundBrushMode.LinearGradient;
			this.MinimumSize = new Size(170, 110);
			this.NameTextBox.AutoSize = false;
			this.AllowDrop = true;

			//context Menu
			this.ContextMenuStrip.Items.Add("Show Role", Resources.png_users, new EventHandler(onAddRole_Click));

			//user symbol
			//this.DesignerViewControl.DesignerControls.Add(_users);
			_users.Parent = this;
			_users.Location = new Point(Location.X, Location.Y + 20);
			_users.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
			_users.Visible = true;
			adjustUserSymbol();

			this.EndUpdate();
		}

		#region Public Members

		#region Override

		public override bool CanDrag
		{
			get { return true; }
		}

		protected override void OnCollapsed(EventArgs e)
		{
			base.OnCollapsed(e);
			_users.Visible = true;
		}

		protected override void OnCollapsing(System.ComponentModel.CancelEventArgs e)
		{
			_users.IsCollapsed = true;
			base.OnCollapsing(e);
			adjustUserSymbol();
		}

		protected override void OnExpanded(EventArgs e)
		{
			base.OnExpanded(e);
			_users.Visible = true;
		}

		protected override void OnExpanding(System.ComponentModel.CancelEventArgs e)
		{
			_users.IsCollapsed = false;
			base.OnExpanding(e);
			adjustUserSymbol();

		}

		public override bool IsDropAllowed(object obj, Point location, MouseButtons button)
		{
			return
				( button == MouseButtons.Right &&
				obj is OrgUnitSymbol ||
				obj is RoleSymbol ||
				obj is OrgSymbol );
		}

		public override bool CheckMouseOver(Point location)
		{
			return base.CheckMouseOver(location);
		}

		public override void DropObject(object obj, Point location, MouseButtons button)
		{
			if ( !( obj is UserSymbol ) && obj != this && button == MouseButtons.Right ) {
				Route r = this.DesignerViewControl.AddRoute((DesignerControl)obj, this);
				r.StartDockDirection = RouteDockDirection.Bottom;
				r.EndDockDirection = RouteDockDirection.Top;
			} else if ( obj is OrgUnitSymbol && obj != this ) {
				DesignerControl ctrl = obj as DesignerControl;
				ctrl.Location = new Point(Location.X, Bounds.Bottom + 30);
				DesignerViewControl.DesignerControls.Add(ctrl);
				Route r = DesignerViewControl.AddRoute(this, ctrl);
				r.StartDockDirection = RouteDockDirection.Bottom;
				r.EndDockDirection = RouteDockDirection.Top;
				//ArrangeConnectedSymbols();
			} else {
				base.DropObject(obj, location, button);
			}
		}

		public override object GetDragObject(Point location, MouseButtons button)
		{
			return this;
		}

		public override void PaintBackground(PaintEventArgs pe)
		{
			base.PaintBackground(pe);

			Rectangle rc = this.ClientRectangle;
			Point pt = this.PointToDesignerView(new Point(rc.X, rc.Bottom - 16));
			pe.Graphics.DrawImage(Resources.png_org_unit, pt.X, pt.Y);
		}

		public override bool IsDropAllowed(Type type, Point location, MouseButtons button)
		{
			return ( type == typeof(UserSymbol) || type == typeof(OrgUnitSymbol) );
		}

		public override void Paint(PaintEventArgs pe)
		{
			if ( IsCollapsed ) {
				base.Paint(pe);
				//	base.PaintChildControls(pe);
			} else {
				base.Paint(pe);
			}
		}

		public override Point GetRouteEnd(RouteDockDirection dock, Route route)
		{
			return new Point(Location.X + Width / 2, Bounds.Top);
		}

		public override Point GetRouteStart(RouteDockDirection dock, Route route)
		{
			return new Point(Location.X + Width / 2, Bounds.Bottom);
		}

		protected override void ReadStandardProperties(System.Xml.XmlReader reader)
		{
			base.ReadStandardProperties(reader);
		}

		protected override void WriteStandardProperties(System.Xml.XmlWriter writer)
		{
			base.WriteStandardProperties(writer);
		}

		protected override void OnLocationChanged(EventArgs e)
		{
			base.OnLocationChanged(e);
			//if ( DesignerViewControl != null ) {
			//    ArrangeConnectedSymbols();
			//}
		}

		#endregion

		public void FillUserList(List<User> list)
		{
			_users.Persons.Clear();
			_users.Persons.AddRange(list);
		}

		public void ArrangeConnectedSymbols(/*DesignerControl lastControl*/)
		{
			_width = 0;
			List<Route> connectedRoutes = new List<Route>();
			connectedRoutes = DesignerViewControl.DesignerControls.Routes.FindAll(new Predicate<Route>(findConnectedRoutes));
			//int width = ( ( connectedRoutes.Count - 1 ) * 180 ) / 2;
			int w = _width;
			w = ( w - Width + ( connectedRoutes.Count - 1 ) * 10 ) / 2;
			foreach ( Route route in connectedRoutes ) {
				int align = ( route.EndControl as OrgUnitSymbol ).ArrangedWidth;
				if ( align != route.EndControl.Width ) {
					route.EndControl.Location =
						new Point(this.Location.X - ( w - align ) / 2, Bottom + 70);
				} else {
					route.EndControl.Location = new Point(this.Location.X - w, Bottom + 70);
				}
				w -= align + 10;
			}
		}

		#endregion

		protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseClick(e);
		}

		private bool findConnectedRoutes(Route route)
		{
			if ( route.StartControl == this ) {
				_width += ( route.EndControl as OrgUnitSymbol ).ArrangedWidth;
				return true;
			} else
				return false;
		}

		private void onAddRole_Click(object sender, EventArgs e)
		{
			//int index = this.DesignerViewControl.AddDesignerControl(new RoleSymbol());
			//this.DesignerViewControl.DesignerControls[index].Location =
			//    new Point(Location.X, Location.Y + Height + 40);
			//this.DesignerViewControl.AddRoute(this, DesignerViewControl.DesignerControls[index]);
		}

		private void adjustUserSymbol()
		{
			_users.Height = this.Height - 60;
			_users.Width = this.Width - 10;
		}
	}

	public class OrgUnitChild : CollapsableSymbol
	{
		public OrgUnitChild()
			: base()
		{
			init();
		}

		void init()
		{
			this.BeginUpdate();

			this.Name = "OrgUnits";
			this.Text = "Org Units";

			this.Border = BorderType.RoundedRectangle;
			this.BackBrushMode = BackgroundBrushMode.LinearGradient;
			this.BackLinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;

			this.NameTextBox.AutoSize = false;
			this.MinimumSize = new Size(160, 50);
			this.AllowDrop = true;

			//context Menu
			//this.ContextMenuStrip.Items.Add("Add Role", Resources.png_users, new EventHandler(onAddRole_Click));

			//collapsing
			this.IsCollapsed = true;
			this.ShowCollapseButton = false; /*collapsed by parent*/

			this.ExpandedBackColor = Color.LightBlue;
			this.ExpandedBackColor2 = Color.SteelBlue;
			this.ExpandedBorderColor = Color.DarkBlue;
			this.ExpandedSize = new Size(170, 220);

			this.CollapsedBackColor = Color.LightBlue;
			this.CollapsedBackColor2 = Color.SteelBlue;
			this.CollapsedBorderColor = Color.DarkBlue;
			this.CollapsedSize = new Size(170, 110);

			// lvContext			
			//_contextListView.Items.Add("Show Details", Resources.png_list, new EventHandler(onEditUser_Click));
			//_contextListView.Items.Add(new ToolStripSeparator());
			//_contextListView.Items.Add("Add Person", Resources.png_user, new EventHandler(onAddUser_Click));
			//_contextListView.Items.Add("Delete Person", Resources.delete, new EventHandler(onDeleteUser_Click));


			// listview
			_lvOrgUnits.Size = new Size(Width - BorderWidth * 2, Height - 70);
			_lvOrgUnits.Location = new Point(Location.X, Location.Y + 15);
			_lvOrgUnits.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left |
				 System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Top;
			_lvOrgUnits.Columns.Add(new Column("Name", Column.ColumnType.TextBox));
			_lvOrgUnits.ContextMenuStrip = _contextListView;
			this.Controls.Add(_lvOrgUnits);

			//fake
			OrganizationalUnit fakeorg = new OrganizationalUnit();
			fakeorg.Name = "Sales";
			_lvOrgUnits.Rows.Add(fakeorg);

			this.EndUpdate();

		}

		public override void PaintBackground(PaintEventArgs pe)
		{
			base.PaintBackground(pe);

			Rectangle rc = this.ClientRectangle;
			Point pt = this.PointToDesignerView(new Point(rc.X, rc.Bottom - 16));
			pe.Graphics.DrawImage(Resources.png_org_unit, pt.X, pt.Y);
			pt.Offset(Resources.png_org_unit.Width + 5, 0);
			if ( _lvOrgUnits.Rows.Count > 0 )
				pe.Graphics.DrawString("CEO: Bob Legrand" /*+ _lvOrgUnits.Rows[0].Items[0].ToString()*/, Font, ForeBrush, (PointF)pt);
			else
				pe.Graphics.DrawString("CEO: n/a", Font, ForeBrush, (PointF)pt);

		}

		protected override Rectangle CalculateClientArea()
		{
			Rectangle r = this.Bounds;
			try {
				r.Inflate(-BorderWidth, -BorderWidth);
			} catch { }
			return r;
		}

		public List<OrganizationalUnit> OrgUnits
		{
			get
			{
				List<OrganizationalUnit> list = new List<OrganizationalUnit>();
				foreach ( Row row in _lvOrgUnits.Rows ) {
					list.Add((OrganizationalUnit)row.Items[0]);
				}
				return list;
			}
		}


		//private string _ceoName = ""; 
		private OpenComposite.Base.Designer.ListView _lvOrgUnits = new OpenComposite.Base.Designer.ListView();
		private ContextMenuStrip _contextListView = new ContextMenuStrip();
	}
}
